﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;
using Microsoft.Xna.Framework.Net;
using Microsoft.Xna.Framework.Storage;

namespace Sublimation
{
    public class SlotWeapon : Slot
    {
        protected double rangedAttackTimerMillis = 0;
        protected float rangedFlightSpeed;
        public float RangedFlightSpeed
        {
            get { return this.rangedFlightSpeed; }
            set { this.rangedFlightSpeed = value; }
        }

        public SlotWeapon(WorldProperties worldProperties, SlotKind kind, Tower ownerTower,bool built)
            : base(worldProperties, kind, ownerTower,built)
        {
            //Position = ownerTower.Position;
            RangedFlightSpeed = 500;
        }

        protected override void LoadContent()
        {
            base.LoadContent();
            Sprite = Game.Content.Load<Texture2D>("Sprites/t_cannon");
        }

        public override void Update(GameTime gameTime)
        {
            base.Update(gameTime);
            rangedAttackTimerMillis += gameTime.ElapsedGameTime.Milliseconds;

            GameObject target = getTarget();

            if (target == null)
            {
                Rotation = ownerTower.Rotation + Orientation;
            }
            if (rangedAttackTimerMillis > attackDelayAffected)
            {
                rangedAttackTimerMillis = 0;
                if (target != null)
                {
                    RangedAttack(target, gameTime);
                }
            }

        }

        public virtual GameObject getTarget()
        {
            GameObject target = null;
            float target_distance = 10000;


            // taget enemies
            foreach (EnemyUnit possible in worldProperties.Enemies)
            {
                float new_target_distance = Vector2.Distance(Position, possible.Position);

                if (new_target_distance < rangeAffected && (target == null || new_target_distance < target_distance))
                {
                    //get the angle with the enemy
                    Vector2 direction = possible.Position - Position;
                    direction.Normalize();
                    direction.Y = -direction.Y;
                    float angle_direction;
                    if (direction.Y >= 0)
                    {
                        angle_direction = (float)Math.Acos(direction.X) % MathHelper.TwoPi;
                    }
                    else
                    {
                        angle_direction = -(float)Math.Acos(direction.X) % MathHelper.TwoPi;
                    }
                    //make sure it's between 0 and 2 PI
                    if (angle_direction < 0)
                    {
                        angle_direction += MathHelper.TwoPi;
                    }

                    float slotRotation = orientation + ownerTower.Rotation;

                    //get the minimum angle
                    float min_angle = ((-slotRotation - angle)) % MathHelper.TwoPi;
                    //make sure it's between 0 and 2 PI
                    if (min_angle < 0)
                    {
                        min_angle += MathHelper.TwoPi;
                    }

                    //get the maximum angle
                    float max_angle = ((-slotRotation + angle)) % MathHelper.TwoPi;
                    //get sure it's between 0 and 2 PI
                    if (max_angle < 0)
                    {
                        max_angle += MathHelper.TwoPi;
                    }

                    bool isTarget = false;
                    if (max_angle < min_angle)
                    {
                        if (angle_direction < max_angle || angle_direction > min_angle && angle_direction > max_angle)
                        {
                            isTarget = true;
                        }
                    }
                    else
                    {
                        if (angle_direction < max_angle && angle_direction > min_angle)
                        {
                            isTarget = true;
                        }
                    }

                    if (isTarget)
                    {
                        // target and it's closer than the existing one
                        target = possible;
                        target_distance = new_target_distance;
                    }
                }
            }

            // check for other targets here
            return target;
        }

        protected virtual void RangedAttack(GameObject target, GameTime gameTime)
        {
            Vector2 position2 = target.Position + (Vector2.Distance(target.Position, Position) / rangedFlightSpeed) * target.Velocity;
            Vector2 bulletVelocity = position2 - Position;
            bulletVelocity.Normalize();
            Rotation =(float) Math.Atan2(bulletVelocity.Y, bulletVelocity.X);
            Vector2 bulletPosition = ownerTower.Position + Vector2.Normalize(bulletVelocity * RangedFlightSpeed) * (ownerTower.CollisionRadius + 10); //TODO: make this actually based on location of the weapon's barrel
            new Arrow(worldProperties, true, bulletPosition, bulletVelocity, RangedFlightSpeed, new Vector2(10, 10), rangeAffected-Vector2.Distance(ownerTower.Position,bulletPosition), damageAffected);
        }
    }
}

